package com.kakarote.hrm.service.reportForms.impl;

import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.hrm.entity.PO.HrmDept;
import com.kakarote.hrm.entity.VO.DeptVO;
import com.kakarote.hrm.entity.VO.reportForms.EmployeeNumVO;
import com.kakarote.hrm.mapper.HrmDeptMapper;
import com.kakarote.hrm.mapper.reportForms.HrmSalaryReportMapper;
import com.kakarote.hrm.service.reportForms.IHrmSalaryReportService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

@Service
public class HrmSalaryReportService extends BaseServiceImpl<HrmSalaryReportMapper, Long> implements IHrmSalaryReportService {

    @Autowired
    private HrmDeptMapper deptMapper;

    @Override
    public List<EmployeeNumVO> queryEmployeeNum() {

        List<DeptVO> deptList = deptMapper.selectAllDeptList();
        JSONObject deptJson= new JSONObject();
        JSONObject deptTree=new JSONObject();
        for(DeptVO de:deptList){
            deptJson.put(de.getDeptId().toString(),de);
        }
        for(DeptVO de:deptList){
            if(de.getLevel()==2){
                if(deptTree.get(de.getDeptId())==null){
                    List<String>childDeptList=new ArrayList<String>();
                    deptTree.put(de.getDeptId().toString(),childDeptList);
                }
            }else if(de.getLevel()>2){
                getParentArr(de,deptJson,de.getDeptId().toString(),deptTree);
            }
        }

        List<EmployeeNumVO>result=baseMapper.queryEmployeeNum();

        List<EmployeeNumVO>data=new ArrayList<EmployeeNumVO>();

        JSONObject employNumJson=new JSONObject();
        for(String key:deptTree.keySet()){
            List<String>childDeptList= (List<String>) deptTree.get(key);
            EmployeeNumVO employeeNumVO=new EmployeeNumVO();
            for(EmployeeNumVO em:result){
                if(childDeptList.indexOf(em.getDeptId())>-1){
                    if(employNumJson.get(key)!=null){
                        employeeNumVO= (EmployeeNumVO) employNumJson.get(key);
                        employeeNumVO=addNum(employeeNumVO,em);
                    }else{
                        DeptVO deptData= (DeptVO) deptJson.get(key);
                        employeeNumVO.setDeptId(key);
                        employeeNumVO.setDeptName(deptData.getName());
                        employeeNumVO.setSortId(deptData.getSortId());
                        employNumJson.put(key,employeeNumVO);
                        employeeNumVO=addNum(employeeNumVO,em);
                    }
                }
            }
            if(employeeNumVO.getDeptId()==null){
                DeptVO deptData= (DeptVO) deptJson.get(key);
                employeeNumVO.setDeptId(key);
                employeeNumVO.setDeptName(deptData.getName());
                employNumJson.put(key,employeeNumVO);
            }
             data.add(employeeNumVO);
        }
        data.sort(
                new Comparator<EmployeeNumVO>() {
                    @Override
                    public int compare(EmployeeNumVO o1, EmployeeNumVO o2) {
                        if ((Long.valueOf(o1.getSortId()) - Long.valueOf(o2.getSortId())) > 0) {
                            return 1;
                        }
                        else if ((Long.valueOf(o1.getSortId()) - Long.valueOf(o2.getSortId())) < 0) {
                            return -1;
                        }
                        else {
                            return 0;
                        }
                    }
                }
        );

        return data;
    }

    public void getParentArr(DeptVO de,JSONObject deptJson,String beginDeptId,JSONObject deptTree){
        String parentId=de.getParentId().toString();
        DeptVO parentDe= (DeptVO) deptJson.get(parentId);
        if(parentDe!=null&&parentDe.getLevel()>2) {
            getParentArr(parentDe,deptJson,beginDeptId,deptTree);
        }else if(parentDe!=null&&parentDe.getLevel()==2){
            List<String>childDeptList=new ArrayList<String>();
            if(deptTree.get(parentDe.getDeptId())!=null) {
                childDeptList = (List<String>) deptTree.get(parentDe.getDeptId().toString());
            }
            childDeptList.add(beginDeptId);
            deptTree.put(parentDe.getDeptId().toString(),childDeptList);
        }
    }

    public EmployeeNumVO addNum(EmployeeNumVO targetData,EmployeeNumVO addData){
        targetData.setWomanNum(targetData.getWomanNum()+addData.getWomanNum());
        targetData.setEmployeeNum(targetData.getEmployeeNum()+addData.getEmployeeNum());
        targetData.setDispatchNum(targetData.getDispatchNum()+addData.getDispatchNum());
        targetData.setOutNum(targetData.getOutNum()+addData.getOutNum());
        targetData.setLaborerNum(targetData.getLaborerNum()+addData.getLaborerNum());
        targetData.setReEmployerNum(targetData.getReEmployerNum()+addData.getReEmployerNum());
        targetData.setOtherNum(targetData.getOtherNum()+addData.getOtherNum());

        targetData.setRetireNum(targetData.getRetireNum()+addData.getRetireNum());
        targetData.setRetiredNum(targetData.getRetiredNum()+addData.getRetiredNum());

        targetData.setAbove55Num(targetData.getAbove55Num()+addData.getAbove55Num());
        targetData.setBetween51Num(targetData.getBetween51Num()+addData.getBetween51Num());
        targetData.setBetween46Num(targetData.getBetween46Num()+addData.getBetween46Num());
        targetData.setBetween41Num(targetData.getBetween41Num()+addData.getBetween41Num());
        targetData.setBetween36Num(targetData.getBetween36Num()+addData.getBetween36Num());
        targetData.setUnder35Num(targetData.getUnder35Num()+addData.getUnder35Num());

        targetData.setDoctorNum(targetData.getDoctorNum()+addData.getDoctorNum());
        targetData.setMasterNum(targetData.getMasterNum()+addData.getMasterNum());
        targetData.setUndergraduateNum(targetData.getUndergraduateNum()+addData.getUndergraduateNum());
        targetData.setJuniorCollegeNum(targetData.getJuniorCollegeNum()+addData.getJuniorCollegeNum());
        targetData.setSecondaryNum(targetData.getSecondaryNum()+addData.getSecondaryNum());
        targetData.setHighSchoolNum(targetData.getHighSchoolNum()+addData.getHighSchoolNum());

        targetData.setHighNum(targetData.getHighNum()+addData.getHighNum());
        targetData.setSubHighNum(targetData.getSubHighNum()+addData.getSubHighNum());
        targetData.setMiddleNum(targetData.getMiddleNum()+addData.getMiddleNum());
        targetData.setAssistantNum(targetData.getAssistantNum()+addData.getAssistantNum());
        targetData.setNormalNum(targetData.getNormalNum()+addData.getNormalNum());

        targetData.setSeniorTechnicianNum(targetData.getSeniorTechnicianNum()+addData.getSeniorTechnicianNum());
        targetData.setTechnicianNum(targetData.getTechnicianNum()+addData.getTechnicianNum());
        targetData.setSeniorEngineerNum(targetData.getSeniorEngineerNum()+addData.getSeniorEngineerNum());
        targetData.setIntermediateNum(targetData.getIntermediateNum()+addData.getIntermediateNum());
        targetData.setJuniorNum(targetData.getJuniorNum()+addData.getJuniorNum());
        return targetData;
    }

    public List<HrmDept> selectDeptList(HrmDept dept) {
        return deptMapper.selectDeptList(dept);
    }


    @Override
    public List<JSONObject> queryManPowerNum() {

        List<YearMonth> monthsThisYear = getMonthsThisYear();
        String selectSql1= "ceil((",selectSql2 = "ceil((",selectSql3 = "ceil((",selectSql4 = "ceil((",selectSql5 = "ceil((",selectSql6 = "ceil((";
        for (YearMonth month:monthsThisYear) {

            String time="";

            String nowMonth=(month.getMonth().getValue() + 1)<9?"0"+(month.getMonth().getValue() + 1):String.valueOf(month.getMonth().getValue() + 1);

            if(month.getMonth().getValue()<12) {
                time = month.getYear() + "-" +nowMonth  + "-01 00:00:00";
            }else{
                time=month.getYear()+"-12-31 23:59:59";
            }
            selectSql1+=" sum( case when whe.company_age_start_time <'"+time+"' then 1 else 0 end)+";
            selectSql2+=" sum( case when t3.wv3='在岗' and whe.company_age_start_time <'"+time+"' then 1 else 0 end)+";
            selectSql3+=" sum( case when whe.company_age_start_time like'%"+month.getYear()+"-"+nowMonth+"%' then 1 else 0 end)+";
            selectSql4+=" sum( case when t3.wv3='劳务派遣' and whe.company_age_start_time <'"+time+"' then 1 else 0 end)+";
            selectSql5+=" sum( case when (t1.wv1='劳务外包' or t1.wv1='其他' or t1.wv1='退休返聘' or t1.wv1='临时工')  and whe.company_age_start_time <'"+time+"' then 1 else 0 end)+";
            selectSql6+=" sum( case when (t3.wv3='离休' or t3.wv3='退休') and whe.company_age_start_time <'"+time+"' then 1 else 0 end)+";
        }
        selectSql1=selectSql1.substring(0, selectSql1.length()-1);
        selectSql2=selectSql2.substring(0, selectSql2.length()-1);
        selectSql3=selectSql3.substring(0, selectSql3.length()-1);
        selectSql4=selectSql4.substring(0, selectSql4.length()-1);
        selectSql5=selectSql5.substring(0, selectSql5.length()-1);
        selectSql6=selectSql6.substring(0, selectSql6.length()-1);
        selectSql1+=")/"+monthsThisYear.size()+") as avg1,";
        selectSql2+=")/"+monthsThisYear.size()+") as avg2,";
        selectSql3+=")/"+monthsThisYear.size()+") as avg3,";
        selectSql4+=")/"+monthsThisYear.size()+") as avg4,";
        selectSql5+=")/"+monthsThisYear.size()+") as avg5,";
        selectSql6+=")/"+monthsThisYear.size()+") as avg6,";

        selectSql1+="sum( case when whe.company_age_start_time <'"+YearMonth.now().getYear()+"-12-31 23:59:59' then 1 else 0 end) as eSum1,";
        selectSql2+="sum( case when t3.wv3='在岗' and  whe.company_age_start_time <'"+YearMonth.now().getYear()+"-12-31 23:59:59' then 1 else 0 end) as eSum2,";
        String nowYearMonth=YearMonth.now().getYear()+"-"+(YearMonth.now().getMonth().getValue()<10?"0"+(YearMonth.now().getMonth().getValue()):String.valueOf(YearMonth.now().getMonth().getValue()));
        selectSql3+="sum( case when whe.company_age_start_time like '%"+nowYearMonth+"%' then 1 else 0 end) as eSum3,";
        selectSql4+="sum( case when t3.wv3='劳务派遣' and whe.company_age_start_time <'"+YearMonth.now().getYear()+"-12-31 23:59:59' then 1 else 0 end) as eSum4,";
        selectSql5+="sum( case when (t1.wv1='劳务外包' or t1.wv1='其他' or t1.wv1='退休返聘' or t1.wv1='临时工') and whe.company_age_start_time <'"+YearMonth.now().getYear()+"-12-31 23:59:59' then 1 else 0 end) as eSum5,";
        selectSql6+="sum( case when (t3.wv3='离休' or t3.wv3='退休') and  whe.company_age_start_time <'"+YearMonth.now().getYear()+"-12-31 23:59:59' then 1 else 0 end) as eSum6";
        String querySql=selectSql1+selectSql2+selectSql3+selectSql4+selectSql5+selectSql6;

        Map<String,Integer>res=baseMapper.queryManpowerNum(querySql);
        String []labelArr={"一、人员管理|（单位：人）","1、企业从业人员人数","--其中：在岗职工","----其中：新入职职工人数","2、企业离、退休职工人数","3、企业内退、不在岗职工人数","4、当年离职人数","5、企业经营管理人员人数","--其中：高管人员","----中层管理人员",
                "----一般管理人员","6、取得专业技术职务任职资格人数","--其中：高级职称（含正高）","----中级职称","----初级职称（含助理、员级）","7、取得技能职业资格人数","--其中：高级技师","----技师","----高级工","----中级工","8、学历情况","--其中：博士研究生人数",
                "----硕士研究生人数","----大学本科人数","----大学专科人数","二、人员薪资|（单位：万元）","1、在岗职工工资总额","--其中：基本工资","----绩效工资","----其他工资","2、劳务派遣人员费用","3.劳务外包人员费用","4、支付离、退休职工费用","福利费",
                "7、五险费用","8、公积金费用","9、年金费用","10、补充医疗保险费用","11、培训费用","12、招聘费用","13、工会会费","14、劳动保护费用","15、其他","三、人力资源效益指标| ","1、在岗职工平均工资（元）","2、在岗职工平均工资（不含外方）（元）",
                "3、人工成本利润率（%）","4、人均利润（万元）","5、人均人工成本（万元）","--其中：从业人员人均人工成本（万元）","6、人均营业收入（万元）","7、人事费用率（%）"
        };
        List<JSONObject>jsonRes=new ArrayList<>();
        for(String label:labelArr){
            JSONObject json=new JSONObject();
            if(label.indexOf("|")>0){
                json.put("label",label.split("\\|")[0]);
                json.put("memo",label.split("\\|")[1]);
            }else{
                json.put("label","");
                json.put("memo",label);
            }
            json.put("endNum","--");
            json.put("revNum","--");
            json.put("remark","--");
            jsonRes.add(json);
        }

        jsonRes.get(1).put("endNum",res.get("eSum1"));
        jsonRes.get(1).put("revNum",res.get("avg1"));
        jsonRes.get(2).put("endNum",res.get("eSum2"));
        jsonRes.get(2).put("revNum",res.get("avg2"));
        jsonRes.get(3).put("endNum",res.get("eSum3"));
        jsonRes.get(3).put("revNum",res.get("avg3"));
        jsonRes.get(4).put("endNum",res.get("eSum4"));
        jsonRes.get(4).put("revNum",res.get("avg4"));

        jsonRes.get(5).put("endNum",res.get("eSum5"));
        jsonRes.get(5).put("revNum",res.get("avg5"));
        jsonRes.get(6).put("endNum",res.get("eSum6"));
        jsonRes.get(6).put("revNum",res.get("avg6"));

        return jsonRes;
    }

    public static List<YearMonth> getMonthsThisYear() {
        List<YearMonth> months = new ArrayList<>();
        YearMonth now = YearMonth.now();
        for (int i = 1; i <= now.getMonth().getValue(); i++) {
            months.add(YearMonth.of(now.getYear(), i));
        }
        return months;
    }
}
